package com.houor.device.controller.data;

import org.houor.utility.NumberUtility;

/**
 * 数据帧
 * 
 * @author Houor
 *
 * @createTime 2017-04-21 22:59
 */
public class ControllerFrame {

	/**
	 * 起始字节
	 */
	private byte start = (byte) 0xA5;

	/**
	 * 数据长度, 2字节, 去除起始符, 结束符和校验符后的长度
	 */
	private short length;

	/**
	 * 控制器标识, 8字节
	 */
	private long deviceID;

	/**
	 * 设备类型
	 */
	private byte deviceType;

	/**
	 * 命令
	 */
	private byte command;

	/**
	 * 状态
	 */
	private byte status;

	/**
	 * 数据信息
	 */
	private byte[] content;
	/**
	 * 校验和
	 */
	private byte checksum;

	/**
	 * 结束字节
	 */
	private byte end = 0x0D;

	public ControllerFrame() {

	}

	public ControllerFrame(short length, long deviceID, byte deviceType, byte command, byte status, byte[] content) {
		super();
		this.length = length;
		this.deviceID = deviceID;
		this.deviceType = deviceType;
		this.command = command;
		this.status = status;
		this.content = content;
		this.checksum = generateCheckSum();
	}

	/**
	 * 根据二进制数组初始化对象
	 * 
	 * @param data
	 */
	public void init(byte[] data) {
		this.start = data[0];
		this.length = NumberUtility.byteArray2Short(new byte[] { data[1], data[2] });
		this.deviceID = NumberUtility.byteArray2Long(new byte[] { data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10] });
		this.deviceType = data[11];
		this.command = data[12];
		this.status = data[13];
		this.content = new byte[this.length - 13];
		System.arraycopy(data, 14, this.content, 0, this.content.length);
		this.checksum = data[data.length - 2];
		this.end = data[data.length - 1];
	}

	/**
	 * 生成校验和
	 * 
	 * @return
	 */
	public byte generateCheckSum() {

		byte sum = 0x00;

		for (byte b : NumberUtility.short2ByteArray(this.length)) {
			sum = (byte) (sum + b);
		}

		for (byte b : NumberUtility.long2ByteArray(this.deviceID)) {
			sum = (byte) (sum + b);
		}

		sum = (byte) (sum + this.deviceType);
		sum = (byte) (sum + this.command);
		sum = (byte) (sum + this.status);

		if (this.content != null && this.content.length != 0) {
			for (byte b : this.content) {
				sum = (byte) (sum + b);
			}
		}

		return sum;
	}

	/**
	 * 检验校验和
	 * 
	 * @return
	 */
	public boolean checkDataCheckSum() {
		if (this.getChecksum() == generateCheckSum())
			return true;
		return false;
	}

	/**
	 * 根据对象生成二进制数组
	 * 
	 * @return
	 */
	public byte[] toByteArray() {
		byte[] result = new byte[this.length + 3];
		result[0] = this.start;
		System.arraycopy(NumberUtility.short2ByteArray(this.length), 0, result, 1, 2);
		System.arraycopy(NumberUtility.long2ByteArray(this.deviceID), 0, result, 3, 8);
		result[11] = this.deviceType;
		result[12] = this.command;
		result[13] = this.status;
		if (this.content != null && this.content.length != 0) {
			System.arraycopy(this.content, 0, result, 14, this.content.length);
		}
		result[result.length - 2] = this.checksum;
		result[result.length - 1] = this.end;
		return result;
	}

	public byte getStart() {
		return start;
	}

	public void setStart(byte start) {
		this.start = start;
	}

	public short getLength() {
		return length;
	}

	public void setLength(short length) {
		this.length = length;
	}

	public long getDeviceID() {
		return deviceID;
	}

	public void setDeviceID(long deviceID) {
		this.deviceID = deviceID;
	}

	public byte getDeviceType() {
		return deviceType;
	}

	public void setDeviceType(byte deviceType) {
		this.deviceType = deviceType;
	}

	public byte getCommand() {
		return command;
	}

	public void setCommand(byte command) {
		this.command = command;
	}

	public byte getStatus() {
		return status;
	}

	public void setStatus(byte status) {
		this.status = status;
	}

	public byte[] getContent() {
		return content;
	}

	public void setContent(byte[] content) {
		this.content = content;
	}

	public byte getChecksum() {
		return checksum;
	}

	public void setChecksum(byte checksum) {
		this.checksum = checksum;
	}

	public byte getEnd() {
		return end;
	}

	public void setEnd(byte end) {
		this.end = end;
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		byte[] print = toByteArray();

		for (int i = 0; i < print.length; i++) {
			sb.append(NumberUtility.formatStringTo2Length(Integer.toHexString(print[i])) + " ");
		}

		return sb.toString();
	}
}
